/***************************************************************
 * Name:      RubyClass.h
 * Purpose:   Code for SketchUp Ruby Extension EventRelay
 * Author:    pecan Heber
 * Created:   2008/10/21
 * Copyright: pecan Heber
 * License:   GPL
 **************************************************************/
/*
	This file is part of Eventrelay, a Ruby extension for SketchUp
	Copyright (C) 2008,2009 Pecan Heber

	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU General Public License
	as published by the Free Software Foundation; either version 2
	of the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#ifndef RubyClass_H
#define RubyClass_H

#include "windows.h"
#include <wx/dynarray.h>
#include <wx/string.h>

//-class HiddenFrame;
class MSW_ProcessMacro;


typedef unsigned long VALUE;
typedef VALUE (*RUBYFUNC) (VALUE);

class HiddenFrame;
extern HiddenFrame* pHiddenFrame;

// declare array type holding all EventRelay instances
WX_DEFINE_ARRAY_LONG(VALUE, ArrayOfRubyEventRelayObj);

// ----------------------------------------------------------------------------
class RubyClassHandler
// ----------------------------------------------------------------------------
{
    // Handles call to and from Ruby class EventRelay
    // Driven from HiddenWindow by way of EventRelay.dll
    // Defines the EventRelay Ruby class and callbacks

    friend class HiddenFrame;

    public:
        RubyClassHandler();
        virtual ~RubyClassHandler();

        bool Call_Ruby_OnKeyDownMethod( UINT key, UINT repeat, UINT flag);
        bool Call_Ruby_OnKeyUpMethod( UINT key, UINT repeat, UINT flag);
        bool Call_Ruby_OnMouseEventMethod( UINT mouseEventType, UINT flags, int x, int y);
        bool Call_Ruby_OnMenuSelected( UINT menuId, wxString menuLabel);
        void Call_Ruby_OnERTimerEvent(UINT objectId);

        void SetHiddenFrame(HiddenFrame* pHiddenFrame){m_pHiddenFrame = pHiddenFrame;}
        HiddenFrame* GetHiddenFrame(){return (HiddenFrame*)pHiddenFrame;}

        void AddRubyObj(VALUE rubyEventRelayObj)
                { m_RubyEventRelayObjs.Add(rubyEventRelayObj); }
        void RemoveRubyObj(VALUE rubyEventRelayObj)
                {   if ( m_RubyEventRelayObjs.Index(rubyEventRelayObj) not_eq wxNOT_FOUND )
                        m_RubyEventRelayObjs.Remove(rubyEventRelayObj);
                }
        int  GetRubyObjCount()
                { return m_RubyEventRelayObjs.GetCount();}
        int  GetRubyObj(int index)
                { return m_RubyEventRelayObjs.Item(index);}

        HiddenFrame* m_pHiddenFrame;
        wxString m_charMouseEventType;

        enum{
            m_typeRMouseDown = 1,
            m_typeLMouseDown,
            m_typeMMouseDown,
            m_typeRMouseUp,
            m_typeLMouseUp,
            m_typeMMouseUp
        };

    protected:
        // Key macro processor
        MSW_ProcessMacro* m_pMacroRunner;

    private:
        // Initialization called from script EventRelay.new
        static  VALUE Initialize(VALUE self);

        //OnKeyDown
        static  VALUE OnKeyDown(VALUE self, VALUE key, VALUE repeat, VALUE flag);
        static  VALUE rbpOnKeyDown(VALUE ThisObj); //protected call to a Ruby method

        //OnKeyUp
        static  VALUE OnKeyUp(VALUE self, VALUE key, VALUE repeat, VALUE flag);
        static  VALUE rbpOnKeyUp(VALUE ThisObj); //protected call to a Ruby method

        // Mouse functions
        static  VALUE rbpOnMouseMethod(VALUE ThisObj); //protected call to a Ruby method
        //OnRButtonDown/Up testing functions. User should override these
        static  VALUE OnRButtonDown(VALUE self, VALUE flags, VALUE x, VALUE y);
        static  VALUE OnRButtonUp(VALUE self, VALUE flags, VALUE x, VALUE y);
        // Menu functions
        static  VALUE rbpOnMenuSelected(VALUE eventRelayObj); //Ruby protected
        static  VALUE ERGetMenuID(VALUE self, VALUE idIn);

        // Timer
        static  VALUE ERTimerStart(VALUE selfIn, VALUE dblSecondsIn);
        static  VALUE rbpOnERTimerEvent(VALUE eventRelayObj); //Ruby protected
        static  VALUE ERTimerStop(VALUE selfIn);
        static  VALUE ERGetVersion(VALUE self);
        static  VALUE ERRemoveObject(VALUE self, VALUE id);

        // logit called from Ruby to write to our log
        static  VALUE Logit (VALUE self, VALUE stringToLog);
        static  VALUE GetMousePosition(VALUE self);
        static  VALUE SendKeyMacro(VALUE self, VALUE rMacroString);
        static  VALUE GetKeyInfo(VALUE selfIn, VALUE vk_keyIn, VALUE vk_flagsIn);
        static  VALUE ERWinFreeze(VALUE self, VALUE stateIn);
        static  VALUE ERSetFocusSketchUp(VALUE self);
        static  VALUE ERSendMenuAction(VALUE self, VALUE menuPathIn);
        static  VALUE ERCmdKeyConfig(VALUE self);
        static  void  FreeObject(void*);
        static  void  MarkObject(void*);

        void  ShowRubyError(int error);
        UINT  GetCharFromVirtualKey( UINT vKeyIn);
        UINT  GetScanCodeFromVirtualKey( UINT vKeyIn);
        bool  MethodExists( const VALUE vObj, const wxString methodName);
        static VALUE rbpMethodExists( VALUE self);
        static VALUE Finalizer(VALUE self, VALUE id);

        VALUE    m_rubyClass;
        VALUE    m_key;
        VALUE    m_repeat;
        VALUE    m_flags;
        LONG     m_x;
        LONG     m_y;
        bool     m_macroProcessIsBusy;
        VALUE    m_holder;
        UINT     m_MenuId;
        //wxString m_MenuLabel;
        wxString m_MenuLabel;
        wxString m_VkString;
        wxString m_KeyMacroSymbol;
        VALUE    m_vMethodExistsObj;
        wxString m_sMethodName;

        // Array of Ruby EventRelay objects created in Ruby interpreter
        ArrayOfRubyEventRelayObj m_RubyEventRelayObjs;
};

#endif // RubyClass_H
